﻿// by shimohana
using System;
using AzukiMap.Map;
using AzukiMap.MapSource;
using Geometries = GisSharpBlog.NetTopologySuite.Geometries;
using GeoAPI.Geometries;
using System.Collections.Generic;

namespace AzukiMap.Layer
{
#if false
    public class JaMapTiledLayer : TiledLayer
    {
        JaMapTileSource _jaMapSource;

        public JaMapTileSource DataSource
        {
            get { return _jaMapSource; }
        }

        public JaMapTiledLayer(JaMapTileSource mapSource, string name)
            : base(mapSource, name)
        {
            _jaMapSource = mapSource;
        }

        public JaMapTiledLayer(JaMapTileSource mapSource, string name, Geometries.Polygon maxExtent)
            : base(mapSource, name, maxExtent)
        {
            _jaMapSource = mapSource;
        }

        protected override string CreateTileReqString(double tileScale, int tlX, int tlY)
        {
            string layerStr = GetLayersString();
            string groupStr = GetGroupsString();

            double scale = tileScale;
            double lat = tlY;
            double lon = tlX;
            int viewWidth = _jaMapSource.TileWidth;
            int viewHeight = _jaMapSource.TileHeight;

            ICoordinate coord = GetGeoPointFromTileCoord(tlX, tlY, tileScale);
            lat = coord.Y;
            lon = coord.X;
            scale = GetPixelPerUnit(viewWidth);
//            scale = 10;

            IPolygon tileExtent = GetTileExtent(tileScale, tlX, tlY);
            scale = tileExtent.EnvelopeInternal.MaxX - tileExtent.EnvelopeInternal.MinX;
            lon = tileExtent.Centroid.X;
            lat = tileExtent.Centroid.Y;
            
            string tileUriStr = "Map?type=base&scale=" + scale + "&lat=" + lat + "&lon=" + lon + "&w=" + viewWidth + "&h=" + viewHeight
                + PutLayerFlags(_jaMapSource.ViewLayerNames)
                + "&cache=true&serial=" + GetSerial();

            return tileUriStr;
        }

        // 複数のレイヤーフラグを設定する
        private string PutLayerFlags(string name) {
	        var ret = "";
            if (name != null)
            {
                var names = name.Split(',');
                for (var i = 0; i < names.Length; i++)
                {
                    ret += PutLayerFlag(names[i]);
                }
            }
	        return ret;
        }
        private string PutLayerFlag(string name)
        {
            bool isView = false;
            if (_jaMapSource.ViewLayers.ContainsKey(name))
            {
                isView = _jaMapSource.ViewLayers[name];
            }
            return "&" + name + "=" + isView;
        }

        private static int serial = 0;
        protected string GetSerial()
        {
            lock(this) {
                serial++; 
            }
            return DateTime.Now.ToString("yyMMddHHmm") + "_" + serial;
        }


        protected override ICoordinate GetGeoPointFromTileCoord(int tileX, int tileY, double tileScale)
        {
            double lon = GetTileLon(tileX, tileScale);
            double lat = GetTileLat(tileY, tileScale);

            ICoordinate geoPoint = new Geometries.Coordinate(lon, lat);

            return geoPoint;
        }


        protected override ICoordinate GetTileOrigin(IPoint point, double tileScale)
        {
            int originX = GetTileOriginX(point.X, tileScale);
            int originY = GetTileOriginY(point.Y, tileScale);

            ICoordinate tileOrigin = new Geometries.Coordinate(originX, originY);

            return tileOrigin;
        }

        int GetTileOriginX(double lon, double tileScale)
        {
            double pixelPerUnit = GetPixelPerUnit(tileScale);
            int tileXNum = (int)Math.Floor(lon * pixelPerUnit / _jaMapSource.TileWidth);
            return _jaMapSource.TileWidth * tileXNum;
        }

        int GetTileOriginY(double lat, double tileScale)
        {
            double pixelPerUnit = GetPixelPerUnit(tileScale);
            int flip = (_mapCoord.FlipY) ? -1 : 1;
            int tileYNum = (int)Math.Floor(lat * pixelPerUnit / _jaMapSource.TileHeight) * flip;
            return _jaMapSource.TileHeight * tileYNum;
        }

        double GetTileLon(int tileX, double tileScale)
        {
            double pixelPerUnit = GetPixelPerUnit(tileScale);
            return (double)tileX / pixelPerUnit;
        }

        double GetTileLat(int tileY, double tileScale)
        {
            double pixelPerUnit = GetPixelPerUnit(tileScale);
            int flip = (_mapCoord.FlipY) ? -1 : 1;
            return (double)tileY / pixelPerUnit * flip;
        }

        string GetLayersString()
        {
            string layerString = "";
            string splitter = "";
            foreach (string layer in _jaMapSource.Layers)
            {
                layerString += layer + splitter;
                splitter = ",";
            }
            return layerString;
        }

        string GetGroupsString()
        {
            string groupString = "";
            string splitter = "";
            foreach (string group in _jaMapSource.Groups)
            {
                groupString += group + splitter;
                splitter = ",";
            }
            return groupString;
        }

        double GetPixelPerUnit(double tileScale)
        {
            int tileDpi = _jaMapSource.Dpi;
            double inchePerUnit = AzukiMapSettings.InchesPerUnit(_jaMapSource.CoordUnit);
            double pixelPerUnit = inchePerUnit * tileDpi / tileScale;

            return pixelPerUnit;
        }

    }
#endif
}
